package com.ruoyi.service;

import com.google.gson.Gson;
import com.google.protobuf.InvalidProtocolBufferException;

import com.ruoyi.protobuf.HisDataOuterClass;
import com.ruoyi.protobuf.HisHealthData;
import com.ruoyi.utils.MyDateTimeUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.util.*;
@Service
public class SleepPreprocessor {
    private static final Logger log = LoggerFactory.getLogger(SleepPreprocessor.class);
    private Gson gson = new Gson();
    public void DataPrepare(byte[] payload) {
        HisDataOuterClass.HisNotification hisNotify = null;
        try {
            hisNotify = HisDataOuterClass.HisNotification.parseFrom(payload);
        } catch (InvalidProtocolBufferException ex) {
            ex.printStackTrace();
            return;
        }
        if(hisNotify.hasHisData()){
            HisDataOuterClass.HisData hisData = hisNotify.getHisData();
            if(hisData.hasHealth()){
                Map sleepMap = new HashMap();
                HisHealthData.HisDataHealth healthData = hisData.getHealth();

                int seq = hisData.getSeq();
                sleepMap.put("Q",seq);

                Date the_data_time = new Date(healthData.getTimeStamp().getDateTime().getSeconds()*1000L);
                Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
                calendar.setTime(the_data_time);
                int hour = calendar.get(Calendar.HOUR_OF_DAY);
                int minute = calendar.get(Calendar.MINUTE);
                int times[] = new int[2];
                times[0] = hour;
                times[1] = minute;
                sleepMap.put("T",times);

                String data_time = MyDateTimeUtils.convert2DateTimeString(healthData.getTimeStamp().getDateTime().getSeconds());
                if(healthData.hasPedoData()){
                    HisHealthData.HisHealthPedo his_pedo = healthData.getPedoData();
                    Map detailMap = new HashMap();
                    detailMap.put("s",his_pedo.getStep());
                    detailMap.put("c",his_pedo.getCalorie());
                    detailMap.put("d",his_pedo.getDistance());
                    detailMap.put("t",his_pedo.getType());
                    detailMap.put("a",his_pedo.getState() & 15);
                    sleepMap.put("P",detailMap);
                }
                if(healthData.hasHrData()){
                    HisHealthData.HisHealthHr his_hr = healthData.getHrData();
                    Map detailMap = new HashMap();
                    if(his_hr.getAvgBpm()>0){
                        detailMap.put("a",his_hr.getAvgBpm());
                    }
                    if(his_hr.getMaxBpm()>0){
                        detailMap.put("x",his_hr.getMaxBpm());
                    }
                    if(his_hr.getMinBpm()>0){
                        detailMap.put("n",his_hr.getMinBpm());
                    }
                    sleepMap.put("H",detailMap);
                }
                if(healthData.hasHrvData()){
                    HisHealthData.HisHealthHrv his_hrv = healthData.getHrvData();
                    Map detailMap = new HashMap();
                    if(his_hrv.getSDNN()>0){
                        detailMap.put("s",his_hrv.getSDNN()/10.0);
                    }
                    if(his_hrv.getRMSSD()>0){
                        detailMap.put("r",his_hrv.getRMSSD()/10.0);
                    }
                    if(his_hrv.getPNN50()>0){
                        detailMap.put("p",his_hrv.getPNN50()/10.0);
                    }
                    if(his_hrv.getMEAN()>0){
                        detailMap.put("m",his_hrv.getMEAN()/10.0);
                    }
                    int fatigue = (int)his_hrv.getFatigue();
                    if(fatigue > -1000){
                        if(fatigue<=0){
                            fatigue = (int)(Math.log((double)his_hrv.getRMSSD())*20);
                        }
                        if(fatigue>0){
                            detailMap.put("f",fatigue);
                        }
                        if(!detailMap.isEmpty()){
                            sleepMap.put("V",detailMap);
                        }
                    }
                }
                if(healthData.hasSleepData()){
                    HisHealthData.HisHealthSleep sleepData = healthData.getSleepData();
                    Map detailMap = new HashMap();
                    detailMap.put("a",sleepData.getSleepDataList());
                    if(sleepData.hasShutDown()){
                        detailMap.put("s", sleepData.getShutDown());
                    }
                    if(sleepData.hasCharge()){
                        detailMap.put("c", sleepData.getCharge());
                    }
                    sleepMap.put("E",detailMap);
                }
                /*
                	save sleep_str with data_time/seq, later to do sleep calculation,
				    need combine all day's sleep_str
                 */
                String sleep_str = gson.toJson(sleepMap);
                log.info(String.format("%s %d %s", data_time, seq, sleep_str));
            }
        }
    }

    /*
    Combine all day's sleep_str to one single string, in format json array.
    sleepDataList should order by datetime
    */
    private String CombineSleepRawData(List<String> sleepList){
        if(sleepList == null || sleepList.size() == 0){
            return "[]";
        }
        StringBuilder sb = new StringBuilder("[");
        for(int i=0;i<sleepList.size();i++){
            String sleepstr = sleepList.get(i);
            sb.append(sleepstr);
            if(i==sleepList.size()-1){
                sb.append("]");
            }
            else{
                sb.append(",");
            }
        }
        return sb.toString();
    }
}
